package rabbitMQ

import (
	"fmt"
	"runtime"
)

type OptMq struct {
	host string
}

func NewOptMq(mqHost string) *OptMq {
	return &OptMq{
		host: mqHost,
	}
}

func (g *OptMq) Publish(queue, exchange, routekey string, msg []byte) error {
	rabbitMQTopics := ProtectRun(NewRabbitMQTopics, queue, exchange, routekey, g.host)
	rabbitMQTopics.PublishTopics(msg)
	return nil
}

func (g *OptMq) PublishDirect(queue, exchange, routekey string, msg []byte, durable bool) error {
	rabbitMQTopics := ProtectRun(NewRabbitMQTopics, queue, exchange, routekey, g.host)
	rabbitMQTopics.PublishDirect(msg, durable)
	return nil
}

func (g *OptMq) PublishDead(queue, exchange, routekey, toExchange, toRouteKey, ttl string, msg []byte) error {
	rabbitMQTopics := ProtectRun(NewRabbitMQTopics, queue, exchange, routekey, g.host)
	rabbitMQTopics.PublishDeadTopics(msg, toExchange, toRouteKey, ttl)
	return nil
}

func (g *OptMq) Amqphandler(queue, exchange, routekey string, f func(body string) (bool, error)) error {
	mq := ProtectRun(NewRabbitMQTopics, queue, exchange, routekey, g.host)
	mq.ConsumeTopics(f)
	return nil
}

func (g *OptMq) AmqphandlerDirect(queue, exchange, routekey string, f func(body string) (bool, error), durable bool) error {
	mq := ProtectRun(NewRabbitMQTopics, queue, exchange, routekey, g.host)
	mq.ConsumeDirect(f, durable)
	return nil
}

func (g *OptMq) AmqphandlerDead(queue, exchange, routekey, toExchange, toRouteKey string, f func(body string) (bool, error)) error {
	mq := ProtectRun(NewRabbitMQTopics, queue, exchange, routekey, g.host)
	mq.ConsumeDead(toExchange, toRouteKey, f)
	return nil
}

// 保护方式允许一个函数
func ProtectRun(f func(queueName, exchangeName, routingKey, rmqURL string) *Rabbit, queueName, exchangeName, routingKey, rmqURL string) *Rabbit {
	// 延迟处理的函数
	defer func() {
		// 发生宕机时，获取panic传递的上下文并打印
		err := recover()
		switch err.(type) {
		case runtime.Error: // 运行时错误
			fmt.Println("runtime error:", err)
		default: // 非运行时错误
			fmt.Println("error:", err)
		}
	}()
	return f(queueName, exchangeName, routingKey, rmqURL)
}
